package com.cnaaa.pay.util;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 2018/10/19 Create by 郭文梁
 * CollectionUtil
 * 集合工具类
 *
 * @author 郭文梁
 * @date 2018/10/19
 */
public class CollectionUtil {
    /**
     * 对集合中的每一个元素进行转换操作，使其变为装有另一种元素的List
     * 示例
     * <pre>
     * <code>
     *      //假设有一个集合为 Collection<String> strs,则可以
     *      List<Integer> fs = CollectionUtil.map(strs, Integer::parseInt);
     * </code>
     * </pre>
     *
     * @param source    源集合
     * @param converter 转换函数
     * @param <S>       源类型
     * @param <T>       目标类型
     * @return 目标List
     */
    public static <S, T> List<T> mapAsList(Collection<S> source, Function<S, T> converter) {
        return source.stream().map(converter).collect(Collectors.toList());
    }

    /**
     * 将集合容器转换未Map
     *
     * @param source         源集合
     * @param keyConverter   Key转换器
     * @param valueConverter Value'转换器
     * @param <S>            源类型
     * @param <K>            Map Key类型
     * @param <V>            Map Value类型
     * @return 目标Map
     */
    public static <S, K, V> Map<K, V> toMap(Collection<S> source, Function<S, K> keyConverter, Function<S, V> valueConverter) {
        return source.stream().collect(Collectors.toMap(keyConverter, valueConverter));
    }

    /**
     * 使Map中的Key连续
     *
     * @param source   源Map
     * @param firstKey 第一个Key
     * @param nextKey  key生成策略
     * @param value    默认值
     * @param size     大小
     * @param <K>      键类型
     * @param <V>      值类型
     * @return 处理结果过Map（=源Map）
     */
    public static <K, V> Map<K, V> continuous(Map<K, V> source, K firstKey, Function<K, K> nextKey, Function<K, V> value, int size) {
        K k = firstKey;
        for (int i = 0; i < size; i++) {
            V v = source.get(k);
            if (v == null) {
                v = value.apply(k);
                source.put(k, v);
            }
            k = nextKey.apply(k);
        }
        return source;
    }

    public static String join(Collection<String> source, String delimiter) {
        Optional<String> result = source.stream().reduce((v1, v2) -> v1 + ',' + v2);
        return result.get();
    }
}
